package com.baizhi.cmfz.config;

import com.baizhi.cmfz.entity.CmfzAdmin;
import com.baizhi.cmfz.mapper.CmfzAdminMapper;
import com.baizhi.cmfz.service.CmfzShiroService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;


/**
 * shiro默认不集成SpringBoot 故不能直接加@Configurations 需要单独配置
 * 这个配置类是为了将认证域从ini中查找 修改为数据源mysql中寻找 找到了返回SimpleAuthenticationInfo 找不到返回null
 * 此类供接下来的配置类@Configuration中使用 故@Autowired现在不用担心
 *
 * extends AuthorizingRealm授权的realm包含两个功能
 * 1.获取认证信息
 * 2.获取授权信息 extends AuthenticatingRealm
 *也就是可以取代AuthenticatingRealm了
 */
@Slf4j
public class AuthorRealm extends AuthorizingRealm {
    @Autowired
    private CmfzAdminMapper cam;
    @Autowired
    private CmfzShiroService css;


    /**
     *获取认证信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        /**
         * 从令牌中获取账号
         */
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();

        /**
         * 通过数据库查询
         */
        CmfzAdmin admin = cam.selectOne(new QueryWrapper<CmfzAdmin>().eq("username", username));
        log.debug(admin.toString());
        /**
         * 查询数据不为为null 就返回info返回
         * 为null 就返回null 会产生异常 证明登陆失败
         */
        if (admin!=null){
            /**
             * 参数1 账号
             * 参数2 密码
             * 参数3 当前realm对象的名字
             */
            //盐值
            ByteSource byteSource = ByteSource.Util.bytes(admin.getSalt());
            return new SimpleAuthenticationInfo(admin.getUsername(),admin.getPassword(),byteSource,this.getName());
        }
        return null;
    }


    /**
     *获取授权信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        /**
         * 多身份 手机号 邮箱 账号
         * getPrimaryPrincipal()获取账号
         */
        //1.获取用户名
        String username = principals.getPrimaryPrincipal().toString();
        //2.查询授权信息  角色名和授权信息permission
        Set<String> roles = css.selectRoleNameByUsername(username);
        Set<String> permissions = css.selectPermissionByUsername(username);
        //3.封装info返回
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roles);
        info.addStringPermissions(permissions);
        return info;
    }
}
